package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageBean;
import com.zzyl.dto.UserDto;
import com.zzyl.entity.*;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.*;
import com.zzyl.properties.SecurityProperties;
import com.zzyl.service.UserService;
import com.zzyl.utils.NoProcessing;
import com.zzyl.utils.ThreadLocalUtil;
import com.zzyl.vo.UserVo;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户表服务实现类
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private SecurityProperties securityProperties;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private PostMapper postMapper;

    @Override
    public PageBean<UserVo> page(Integer pageNum, Integer pageSize, UserDto userDto) {
        if (ObjectUtil.isNotEmpty(userDto.getDeptNo())) {
            /*提取部门编号的有效位*/
            userDto.setDeptNo(NoProcessing.processString(userDto.getDeptNo()));
        }
        /*分页*/
        PageHelper.startPage(pageNum, pageSize);
       /* Page<UserVo> page = userMapper.getPage(userDto);
        return PageBean.of(page, UserVo.class);*/
        Page<User> page = userMapper.selectPage(userDto);
        PageBean<UserVo> pageBean = PageBean.of(page, UserVo.class);
        if (CollUtil.isEmpty(pageBean.getRecords())) {
            return pageBean;
        }
        pageBean.getRecords().forEach(userVo -> {
            List<Role> roleList = roleMapper.findRoleListByUserId(userVo.getId());
            List<String> ids = CollUtil.getFieldValues(roleList, "id", String.class);
            List<String> names = CollUtil.getFieldValues(roleList, "roleName", String.class);
            userVo.setRoleVoIds(Set.copyOf(ids));
            userVo.setRoleLabels(Set.copyOf(names));
        });
        return pageBean;
    }


    @Transactional
    @Override
    public void createUser(UserDto userDto) {
        //根据部门编号查询，是否是最底层的部门，如果不是，不允许添加用户
        int count = deptMapper.isLowestDept(userDto.getDeptNo());
        if (count > 0) {
            throw new BaseException(BasicEnum.USER_LOCATED_BOTTOMED_DEPT);
        }
        User user = BeanUtil.toBean(userDto, User.class);
        user.setDataState("0");
        user.setUsername(userDto.getEmail());
        user.setAvatar("https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png");
        user.setNickName(userDto.getRealName());
        user.setRemark(userDto.getRealName());
        user.setIsLeader(0);
        user.setPassword(BCrypt.hashpw(securityProperties.getDefaultPassword(), BCrypt.gensalt()));
        userMapper.insert(user);
        /*保存用户角色中间表*/
        List<UserRole> userRoles = Lists.newArrayList();
        userDto.getRoleVoIds().forEach(r -> userRoles.add(UserRole.builder()
                .userId(user.getId())
                .roleId(Long.valueOf(r))
                .dataState("0")
                .build()));
        userRoleMapper.batchInsert(userRoles);
    }

    @Transactional
    @Override
    public void updateUser(UserDto userDto) {
        //根据部门编号查询，是否是最底层的部门，如果不是，不允许添加用户
        int count = deptMapper.isLowestDept(userDto.getDeptNo());
        if (count > 0) {
            throw new BaseException(BasicEnum.USER_LOCATED_BOTTOMED_DEPT);
        }
        User user = BeanUtil.toBean(userDto, User.class);

        userMapper.updateByPrimaryKeySelective(user);
        /*如果角色为空*/
        if (CollUtil.isEmpty(userDto.getRoleVoIds())) {
            return;
        }
        /*删除中间表*/
        userRoleMapper.deleteUserRoleByUserId(user.getId());
        /*保存用户角色中间表*/
        List<UserRole> userRoles = Lists.newArrayList();
        userDto.getRoleVoIds().forEach(r -> userRoles.add(UserRole.builder()
                .userId(user.getId())
                .roleId(Long.valueOf(r))
                .dataState("0")
                .build()));
        userRoleMapper.batchInsert(userRoles);
        /*效果相同*/
       /* userDto.getRoleVoIds().forEach(roleVoId -> {
            UserRole userRole = UserRole.builder()
                    .userId(user.getId())
                    .roleId(Long.valueOf(roleVoId))
                    .dataState("0")
                    .build();
            userRoleMapper.insert(userRole);
        });*/
    }

    @Transactional
    @Override
    public void remove(String userIds) {

        userMapper.deleteByPrimaryKey(Long.valueOf(userIds));

        userRoleMapper.deleteUserRoleByUserId(Long.valueOf(userIds));
    }

    @Override
    public void isEnable(Long id, String status) {
        User user = User.builder().dataState(status).id(id).build();
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public List<UserVo> list(UserDto userDto) {
        List<User> users = userMapper.selectList();
        return BeanUtil.copyToList(users, UserVo.class);
    }

    @Override
    public void resetPasswords(String userId) {
        User user = User.builder()
                .password(BCrypt.hashpw(securityProperties.getDefaultPassword(), BCrypt.gensalt()))
                .id(Long.valueOf(userId))
                .build();
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public UserVo currentUser() {
        Long id = ThreadLocalUtil.get();
        User user = userMapper.selectByPrimaryKey(id);
        UserVo userVo = BeanUtil.toBean(user, UserVo.class);

        List<Role> roleList = roleMapper.findRoleListByUserId(userVo.getId());
        Set<String> roleNames = roleList.stream().map(Role::getRoleName).collect(Collectors.toSet());
        userVo.setRoleNames(roleNames);

        Dept dept = deptMapper.selectByDeptNo(user.getDeptNo());
        userVo.setDeptName(dept.getDeptName());

        Post post = postMapper.selectByPostNo(user.getPostNo());
        userVo.setPostName(post.getPostName());

        return userVo;
    }
}

